# This file contains the fastlane.tools configuration
# You can find the documentation at https://docs.fastlane.tools
#
# For a list of all available actions, check out
#
#     https://docs.fastlane.tools/actions
#
# For a list of all available plugins, check out
#
#     https://docs.fastlane.tools/plugins/available-plugins
#
require 'spaceship'

default_platform(:ios)

# Configuration
COMMIT_MESSAGE = "skipci: Automatic version increment"

def commit_ag_build_bump()
  FastlaneCore::CommandExecutor.execute(command: "git add ..",
                                        print_all: true,
                                        error: proc do |error_output|
                                          UI.error("Failed to run git add: #{error_output}")
                                        end)
  FastlaneCore::CommandExecutor.execute(command: "git commit -m '#{COMMIT_MESSAGE}'",
                                        print_all: true,
                                        error: proc do |error_output|
                                          UI.error("Failed to run git commit: #{error_output}")
                                        end)
end

def zip_archive()
  archive_path = "../#{ENV['OUTPUT_DIRECTORY']}/#{ENV['ARCHIVE_NAME']}"
  command = "/usr/bin/ditto -c -k --keepParent \"#{archive_path}\" \"#{archive_path}.zip\""

  FastlaneCore::CommandExecutor.execute(command: command,
                                        print_all: true,
                                        error: proc do |error_output|
                                          UI.error("Failed to run zip_archive: #{error_output}")
                                        end)
end

def clean()
  FastlaneCore::CommandExecutor.execute(command: "rm -rf ../#{ENV['OUTPUT_DIRECTORY']}",
                                        print_all: true,
                                        error: proc do |error_output|
                                          UI.error("Failed to run clean: #{error_output}")
                                        end)
end

def prepare_key()
  # https://docs.fastlane.tools/app-store-connect-api/#using-an-app-store-connect-api-key
  app_store_connect_api_key(
    key_id: "696F7D6QK5",
    issuer_id: "b7f9918a-6dca-4ef0-ae88-b5038d3c239b",
    key_filepath: "fastlane/AuthKeyASL.p8",
    # see the issue here: https://github.com/fastlane/fastlane/issues/19072
    # TODO: remove when the issue is fixed in Fastlane and we update.
    duration: 500, # optional
    in_house: false, # optional but may be required if using match/sigh
  )
end

def getIssuerId()
  if ENV['TEAM_ID'] == "N33TQXN8C7"
      return "69a6de7f-6896-47e3-e053-5b8c7c11a4d1"
  else
      return "b7f9918a-6dca-4ef0-ae88-b5038d3c239b"
  end
end

def getCertId()
  if ENV['TEAM_ID'] == "N33TQXN8C7"
      puts("KOKOKO") # FIXME remove?
      return "L856K7RA82"
  else
      puts("QWEQWEWQE") # FIXME remove?
      return "696F7D6QK5"
  end
end

def getAuthKey()
  # return "fastlane/AuthKey.p8"
  # FIXME replace
  if ENV['TEAM_ID'] == "N33TQXN8C7"
      return "fastlane/AuthKey.p8"
  else
    return "fastlane/AuthKeyASL.p8"
  end
end

platform :ios do
  desc "Runs unit tests"
  lane :tests do
    run_tests(
      scheme: ENV['BUILD_SCHEME'],
      output_types: "junit",
      clean: true,
      code_coverage: true,
      prelaunch_simulator: true,
    )
  end

  desc "Runs unit SDK tests"
  lane :tests_sdk do
    run_tests(
      scheme: "AdGuardSDKTests",
      output_types: "junit",
      clean: true,
      code_coverage: true,
      prelaunch_simulator: true,
    )
  end

  desc "Builds app for appstore"
  lane :build do |options|
    clean()
    prepare_key()

    if !options[:ignore_match]
      match(type: "appstore")
    end
    build_app(
      scheme: ENV['BUILD_SCHEME'],
      output_directory: ENV['OUTPUT_DIRECTORY'],
      include_bitcode: false,
      include_symbols: true,
      clean: true,
      archive_path: "#{ENV['OUTPUT_DIRECTORY']}/#{ENV['ARCHIVE_NAME']}",
    )
    write_build_info( 
      xcconfig: ENV['BUILD_NUMBER_XCCONFIG_PATH'],
      build_info_output: "#{ENV['OUTPUT_DIRECTORY']}/build.txt",
    )
    zip_archive()

    if options[:upload_dsym]
      upload_dsym()
    end
  end

  desc "Builds adhoc build for inner testing"
  lane :adhoc do |options|
    clean()
    prepare_key()

    app_identifiers_to_match = ENV['APP_IDENTIFIERS_TO_MATCH'].gsub("\n", "").gsub(" ", "")

    # This is a potentially dangerous place when creating new targets.
    #
    # To catch more than a glimpse of the process of signing targets using profiles we need to discuss XCode build process.
    # Each target has a build configuration. There are two configurations by default: debug and release.
    # 'Debug' build is signing with 'Development' profile whereas 'Release' build is signing with 'AppStore' profile.
    # 'AdHoc' profile does not appear in any of the configurations.
    # One of the intermediate stages of the XCode build is checking for the presence of a default profile and the default
    # profile is 'AppStore'. Herewith, the validity of the profile is not checked - only its presence. The validity of the
    # profile will be checked when signing, in which the 'AdHoc' profile will be used. Thus, the absence of an 'AppStore'
    # profile breaks the build. We match an 'AppStore' profile in read-only mode so that it appears on the machine,
    # meanwhile, time is not wasted on an expensive operation (not read-only mode).
    #
    # This solution is not flexible enough.
    # A good solution may be to create an additional configuration that meets the 'AdHoc' profile out-of-the-box.
    # But this leads to another less obvious problem. The build of dependencies is directly related to the configuration
    # of the target. Going beyond the standard configurations, we break the logic of dependencies building.
    #
    # As a result, to stay in the legal field of XCode and at the same time not suffer from gut-wrenching restrictions
    # we should learn how to resolve dependency configurations for custom target configurations.
    match(type: "appstore", readonly: true)
    if !options[:ignore_match]
      match(app_identifier: app_identifiers_to_match, type: "adhoc", force_for_new_devices: true)
    else
      match(app_identifier: app_identifiers_to_match, type: "adhoc", readonly: true)
    end

    build_app(
      export_method: "ad-hoc",
      scheme: ENV['BUILD_SCHEME'],
      output_directory: ENV['OUTPUT_DIRECTORY'],
      include_bitcode: false,
      include_symbols: true,
      archive_path: "#{ENV['OUTPUT_DIRECTORY']}/#{ENV['ARCHIVE_NAME']}",
    )
    write_build_info(
      xcconfig: ENV['BUILD_NUMBER_XCCONFIG_PATH'],
      build_info_output: "#{ENV['OUTPUT_DIRECTORY']}/build.txt",
    )
    zip_archive()
  end

  desc "Increments the build number and commits to the repo"
  lane :increment do
    # Ensure that your git status is not dirty
    ensure_git_status_clean

    # Increment the build number (not the version number)
    increment_ag_build(xcconfig: ENV['BUILD_NUMBER_XCCONFIG_PATH'])

    # Commit
    commit_ag_build_bump()

    # Push the new commit and tag back to your git remote
    push_to_git_remote
  end

  desc "Uploads the build to testflight"
  lane :testflight_beta do
    prepare_key()

    # Uploads the build without actually submitting it
    upload_to_testflight(
      skip_submission: true,
      skip_waiting_for_build_processing: true,
      ipa: "#{ENV['OUTPUT_DIRECTORY']}/#{ENV['IPA_NAME']}"
    )
  end
end

lane :prepare do
  prepare_key()

  match(type: "development", readonly: true, generate_apple_certs: true, platform: "ios", team_id: ENV['TEAM_ID'])
  match(type: "appstore", readonly: true, generate_apple_certs: true, platform: "ios", team_id: ENV['TEAM_ID'])
  match(type: "adhoc", readonly: true, generate_apple_certs: true, platform: "ios", team_id: ENV['TEAM_ID'])
end

# Run this only if you need to generate certs and provisioning profiles
lane :generate do
  prepare_key()

  match(type: "development", readonly: false, force: true, generate_apple_certs: true, platform: "ios", team_id: ENV['TEAM_ID'])
  match(type: "appstore", readonly: false, force: true, generate_apple_certs: true, platform: "ios", team_id: ENV['TEAM_ID'])
  match(type: "adhoc", readonly: false, force: true, generate_apple_certs: true, platform: "ios", team_id: ENV['TEAM_ID'])
end

# Prepare fastlane session for CI
lane :auth do
  desc "Authorize the apple ID in order to acquire new session"
  Spaceship::SpaceauthRunner.new(username: ENV['APPLE_ID']).run

  # It seems that the session that is printed by fastlane works for just 30 minutes
  # The reason might be that only a limited set of cookies are printed by default.
  # Instead, we're using all cookies obtained by spaceauth:
  # https://github.com/fastlane/fastlane/issues/14301#issuecomment-479281223

  UI.message("Reading the spaceship cookie value")
  file_data = File.read("#{ENV['HOME']}/.fastlane/spaceship/#{ENV['APPLE_ID']}/cookie")
  cookie = file_data.gsub("\n", "\\n")

  UI.message("Ignore the previous FASTLANE_SESSION, use the new one below")
  UI.message("Pass the following via the FASTLANE_SESSION environment variable:")
  UI.message("#{cookie}".cyan.underline);
end

# upload dsym files to sentry
lane :upload_dsym do
  sentry_upload_dsym(
      auth_token: "#{ENV['bamboo_sentryAuthTokenProductsPassword']}",
      org_slug: 'adg',
      project_slug: 'adguard-ios',
      url: 'https://s10.adtidy.org/',
      dsym_path: "#{ENV['OUTPUT_DIRECTORY']}/#{ENV['DSYM_NAME']}"
    )
end
